<script setup lang="ts">
import { nextTick, onMounted, reactive, ref, shallowRef } from 'vue'
import { useRoute } from 'vue-router'

import {
    Finished,
    Edit,
    Delete,
    Download,
    RefreshRight
} from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import type { Action } from 'element-plus'

import NavTop from '../components/popup/NavTop.vue'
import CollectionEdit from '../components/popup/CollectionEdit.vue'

import { releasesRequest } from '../utils/fetch'
import { deepClone } from '../utils/json'
import { merge } from 'lodash-es'

const formRef = shallowRef()

const editRef = shallowRef()
const showEdit = ref(false)

const route = useRoute()

const setting = reactive({
    position: 'right',
    autoFullScreen: true,
    borderRadius: false,
    alwaysOnTop: true,
    alwaysOnTopLevel: 'floating',
    opacity: 100,
    theme: 'image',
    source: '',
    version: '',
    sourceType: 1,
    home: 'https://www.bing.com',
    menus: [] as Array<Collection>,
    verticalWebsiteHost: 'www.douyin.com',
    updateLoading: false,
    extensionPath: ''
})

const redirectHash = ref('/')

const validateURL = (_: any, value: any, callback: any) => {
    if (!/^https?:\/\//.test(value)) {
        callback(new Error('请输入正确的地址（以 http:// 或 https:// 开头）'))
    } else {
        callback()
    }
}

const rules = reactive({
    home: [
        { required: true, message: '请输入首页地址', trigger: 'blur' },
        { validator: validateURL, trigger: 'blur' }
    ],
    source: [
        { required: true, message: '请选择广告源', trigger: 'change' },
        { validator: validateURL, trigger: 'blur' }
    ]
})

const release = reactive({
    up: false,
    href: '',
    assets: [] as any[]
})

const active = ref('global')

const options = reactive({
    alwaysOnTopLevel: [
        { label: 'floating', value: 'floating' },
        { label: 'modal-panel', value: 'modal-panel' },
        { label: 'status', value: 'status' },
        { label: 'screen-saver', value: 'screen-saver' },
    ],
    position: [
        { label: '右下显示', value: 'right' },
        { label: '左下显示', value: 'left' }
    ],
    theme: [
        { label: '图片', value: 'image' },
        { label: '文字', value: 'text' }
    ],
    adsSourceType: [
        { label: '一级域名', value: 0 },
        { label: '二级域名', value: 1 },
        { label: '自定义', value: 2 }
    ]
})

const handleAdsSourceTypeChange = (value: any) => {
    switch (value) {
        case 0:
            setting.source = 'https://unshell.github.io/expand/ads.html'
            break
        case 1:
            setting.source = 'https://finch.js.cool/expand/ads.html'
            break
        case 2:
            setting.source = ''
            break
    }
}

const handleOpacityChange = (value: any) => {
    document.body.style.opacity = (value / 100).toString()
}

const handleNodeEdit = async (data: any) => {
    showEdit.value = true
    await nextTick()
    editRef.value?.open(data)
}

const handleEditConfirm = (data: Collection) => {
    for (let i = 0; i < setting.menus.length; i++) {
        if (setting.menus[i].id === data.id) {
            merge(setting.menus[i], data)
            break
        }
    }
}

const handleNodeRemove = (_: any, data: any) => {
    const index = setting.menus.findIndex(menu => menu.id === data.id)
    if (index !== -1) {
        setting.menus.splice(index, 1)
    }
}

const handleUpdateInsertJs = () => {
    setting.updateLoading = true
    window.ipcRenderer.send('update-insert-js')
}

const handleExtensionPath = async () => {
    const result = await window.ipcRenderer.invoke('select-extension-folder', !setting.extensionPath)
    if (result.status) {
        ElMessage.success(result.msg)
        setting.extensionPath = result.data
    } else {
        ElMessage.error(result.msg)
    }
}

const openResourceFolder = () => {
    window.ipcRenderer.send('open-resource-folder')
}

const handleQuit = () => {
    // 保存配置
    ElMessageBox.confirm(`即将返回${redirectHash.value === '/' ? '主界面' : '“伪微信”界面'}，按下确认后配置将保存！`, '温馨提示', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        callback: async (active: Action) => {
            if (active === 'confirm') {
                await formRef.value?.validate()
                let clone = deepClone(setting)
                clone.opacity = clone.opacity / 100
                window.ipcRenderer.send('write-config', clone)
            }
            window.ipcRenderer.send('load-hash', redirectHash.value)
        },
    })
}

onMounted(async () => {
    const {
        query: { redirect }
    } = route

    if (redirect) {
        redirectHash.value = redirect as string
    }

    handleAdsSourceTypeChange(setting.sourceType)
    let config = await window.ipcRenderer.invoke('read-config')
    config.opacity = config.opacity * 100
    merge(setting, config)
    for (let i = 0; i < setting.menus.length; i++) {
        let menu = setting.menus[i]
        menu.id = menu.id || window.electronIpc.randomUUID()
    }
    fetch(releasesRequest).then(response => response.json()) // 解析 JSON 数据
        .then((releases: any) => { // 处理数据
            let last = releases[0], tagName = last.tag_name,
                lastVersion = tagName.replace('FishAdsApp-v-', ''), name = last.name;
            if (lastVersion > setting.version) {
                ElNotification({
                    title: '有新版本',
                    message: name,
                    type: 'primary',
                    position: 'bottom-right'
                })
                release.up = true
                release.assets = last.assets.filter((asset: any) => asset.name.endsWith('.exe'))
            }
        }).catch((error: any) => console.error(error))

    window.ipcRenderer.on('update-complete', () => {
        setting.updateLoading = false
        ElMessage({
            message: '更新完成，快去试试吧！',
            type: 'success',
        })
    })

    window.ipcRenderer.on('update-error', (_, errorMessage) => {
        setting.updateLoading = false
        ElMessage.error(`更新失败，原因：${errorMessage}`)
    })
})
</script>
<template>
    <nav-top :app-name="'常用项配置（按右上角按钮可保存设置并返回主界面）'" :border-radius="setting.borderRadius" :close-icon="Finished"
        :close-type="'primary'" @quit="handleQuit" />
    <el-container class="setting" :style="{
        'border-bottom-left-radius': setting.borderRadius ? '8px' : '0px',
        'border-bottom-right-radius': setting.borderRadius ? '8px' : '0px'
    }">
        <el-aside>
            <p>配置</p>
            <el-link :class="active === 'global' ? 'active' : ''" underline="never"
                @click="active = 'global'">全局配置</el-link>
            <el-link :class="active === 'ads' ? 'active' : ''" underline="never" @click="active = 'ads'">广告配置</el-link>
            <el-link :class="active === 'shortcut' ? 'active' : ''" underline="never"
                @click="active = 'shortcut'">快捷键说明</el-link>
            <p>书签</p>
            <el-link :class="active === 'collection' ? 'active' : ''" underline="never"
                @click="active = 'collection'">收藏管理</el-link>
            <p>版本</p>
            <el-link :class="active === 'version' ? 'active' : ''" underline="never"
                @click="active = 'version'">版本信息</el-link>
        </el-aside>
        <el-container>
            <el-form ref="formRef" v-if="active === 'global'" label-position="right" label-width="auto" :model="setting"
                :rules="rules" status-icon>
                <el-form-item label="弹层显示:" prop="position">
                    <el-segmented v-model="setting.position" :options="options.position" />
                </el-form-item>
                <el-form-item label="自动网页全屏:" prop="autoFullScreen">
                    <el-switch v-model="setting.autoFullScreen" active-text="开启" inactive-text="禁用" />
                </el-form-item>
                <el-form-item label="窗口置顶:" prop="alwaysOnTop">
                    <el-switch v-model="setting.alwaysOnTop" active-text="开启" inactive-text="禁用" />
                </el-form-item>
                <el-form-item label="窗口样式:" prop="borderRadius">
                    <el-switch v-model="setting.borderRadius" active-text="圆角" inactive-text="直角" />
                </el-form-item>
                <el-form-item label="置顶等级:" prop="alwaysOnTopLevel">
                    <el-popover class="box-item" title="置顶等级强度" :width="400" placement="top-start">
                        <el-text type="success">从左至右依次变强</el-text><br />
                        floating < modal-panel < status < screen-saver<br />
                        默认为 floating，悬浮窗口级别，略高于普通窗口<br />
                        最高级别 screen-saver，屏保程序级别，是最高层级之一<br />
                        <template #reference>
                            <el-segmented v-model="setting.alwaysOnTopLevel" :options="options.alwaysOnTopLevel" />
                        </template>
                    </el-popover>
                </el-form-item>
                <el-form-item label="窗口透明度:" prop="opacity">
                    <el-slider v-model="setting.opacity" :step="10" :min="20" show-stops @input="handleOpacityChange" />
                </el-form-item>
                <el-form-item label="首页地址:" prop="home">
                    <el-input v-model="setting.home" placeholder="请输入首页地址">
                        <template #append>
                            <el-button :icon="RefreshRight" title="重置" @click="setting.home = 'https://www.bing.com'" />
                        </template>
                    </el-input>
                </el-form-item>
                <el-form-item label="竖屏网站:" prop="verticalWebsiteHost">
                    <el-popover class="box-item" title="如何配置竖屏网站？" trigger="click" :width="570" placement="top-start">
                        以抖音为例：<br />访问的网址为 https://<el-text type="success">www.douyin.com</el-text>/?recommend=1，只要获取绿色部分就行。<br /><br />
                        多个域名请用英文逗号隔开，例如：<br /> www.douyin.com,www.bilibili.com,v.qq.com<br />
                        <el-text type="danger">只有竖屏视频网站设置为竖屏显示才能有更好的体验，除了竖屏显示外网站可能还需要另外的优化，实在搞不明白怎么配置或者需要额外的优化可以私信作者。</el-text>
                        <template #reference>
                            <el-input v-model="setting.verticalWebsiteHost" :rows="3" type="textarea"
                                placeholder="请输入竖屏网站域名，多个以逗号隔开">
                            </el-input>
                        </template>
                    </el-popover>
                </el-form-item>
                <el-form-item label="网页全屏脚本:" prop="autoFullScreen">
                    <el-popover class="box-item" title="什么时候需要更新？" :width="350" placement="top-start">
                        <el-text type="success">优化脚本与全屏脚本在同一文件</el-text>，由<el-text tag="mark">视频网站变更</el-text>导致的全屏功能失效或者<el-text tag="mark">与作者沟通过</el-text>特殊网站优化时可以点击更新！
                        <template #reference>
                            <el-button type="primary" text :loading="setting.updateLoading"
                                @click="handleUpdateInsertJs">点击更新</el-button>
                        </template>
                    </el-popover>
                </el-form-item>
                <el-form-item label="浏览器插件:" prop="extensionPath">
                    <el-popover class="box-item" title="如何加入浏览器插件？" :width="350" placement="top-start">
                        <el-text tag="mark">选择解压后的插件文件夹</el-text>，若插件加载成功也不一定所有功能都生效，具体请查看 Electron 开发文档中对 “Chrome 扩展支持”
                        的描述。
                        <template #reference>
                            <el-button :type="setting.extensionPath ? 'danger' : 'primary'" text
                                @click="handleExtensionPath">
                                {{ setting.extensionPath ? '移除插件' : '选择插件' }}
                            </el-button>
                        </template>
                    </el-popover>
                </el-form-item>
                <el-form-item label="本地资源目录:" prop="extensionPath">
                    <el-popover class="box-item" title="本地资源目录里有什么？" :width="350" placement="top-start">
                        目录中主要存放着一些缓存和日志文件，但重要的是<el-text tag="b">配置文件（config.json）</el-text>和 “微信” 头像等图片<el-text tag="b">资源文件夹（wechat_resource）</el-text>这些关于用户的内容。
                        <template #reference>
                            <el-button type="primary" text @click="openResourceFolder">
                                打开文件夹
                            </el-button>
                        </template>
                    </el-popover>
                </el-form-item>
            </el-form>
            <el-form ref="formRef" v-if="active === 'ads'" label-position="right" label-width="auto" :model="setting"
                :rules="rules" status-icon>
                <el-form-item label="广告样式:" prop="theme">
                    <el-segmented v-model="setting.theme" :options="options.theme" />
                </el-form-item>
                <el-form-item label="广告来源:" prop="sourceType">
                    <el-popover class="box-item" title="什么是广告来源？" :width="400" placement="top-start">
                        <el-text type="success">
                            广告来源是进入弹层时显示的广告网站地址，目前广告网站由作者维护且不定时更新（广告内容由 AI生成）！</el-text><br />
                        一级域名：确保广告能访问，但是速度慢（服务器在国外）<br />
                        二级域名：速度快，但是可能会失效（一般情况不会）<br />
                        自定义：防止域名失效，作为备用地址（正常情况可忽略）
                        <template #reference>
                            <el-segmented v-model="setting.sourceType" :options="options.adsSourceType"
                                @change="handleAdsSourceTypeChange" />
                        </template>
                    </el-popover>
                </el-form-item>
                <el-form-item label="广告地址:" prop="source" v-if="setting.sourceType == 2">
                    <el-input v-model="setting.source" :disabled="setting.sourceType != 2"
                        placeholder="请输入广告地址"></el-input>
                </el-form-item>
            </el-form>
            <el-descriptions v-if="active === 'shortcut'" :column="1" direction="vertical">
                <el-descriptions-item label="关闭应用:">Ctrl+Alt+D</el-descriptions-item>
                <el-descriptions-item label="隐藏应用:">Esc（可以在系统托盘中重新唤出）</el-descriptions-item>
                <el-descriptions-item label="切换置顶:">Ctrl+Alt+T</el-descriptions-item>
                <el-descriptions-item v-if="false" label="打开调试:">Ctrl+Alt+F12</el-descriptions-item>
            </el-descriptions>
            <el-tree v-if="active === 'collection'" :data="setting.menus" :props="{
                label: 'title'
            }" node-key="id" empty-text="还没有数据，快去收藏吧" draggable>
                <template #default="{ node, data }">
                    <div class="collection-node">
                        <span>{{ node.label }}</span>
                        <div>
                            <el-button type="primary" link @click="handleNodeEdit(data)" :icon="Edit">
                                编辑
                            </el-button>
                            <el-button style="margin-left: 4px" type="danger" link :icon="Delete"
                                @click="handleNodeRemove(node, data)">
                                删除
                            </el-button>
                        </div>
                    </div>
                </template>
            </el-tree>
            <el-descriptions v-if="active === 'version'" :column="1" direction="vertical">
                <el-descriptions-item label="当前版本：">{{ setting.version }}</el-descriptions-item>
                <el-descriptions-item>
                    <template #label>
                        <el-badge :is-dot="release.up">版本更新：</el-badge>
                    </template>
                    <template v-if="release.up">
                        <el-link type="primary" v-for="asset in release.assets" :href="asset.browser_download_url"
                            underline="never" :icon="Download">&nbsp;{{ asset.name }}</el-link>
                    </template>
                    <el-button v-else type="info" link>已经是最新版本</el-button>
                </el-descriptions-item>
            </el-descriptions>
        </el-container>
    </el-container>
    <collection-edit v-if="showEdit" ref="editRef" @confirm="handleEditConfirm" @close="showEdit = false" />
</template>
<style lang="scss" scoped>
.setting {
    height: calc(100vh - 42px);
    background-color: #fff;

    .el-aside {
        width: 200px;

        p {
            font-size: 16px;
            font-weight: 600;
            color: #000;
            margin: 10px;
        }

        .el-link {
            display: block;
            padding: 10px 0 10px 25px;

            &.active {
                background-color: rgba(#409eff, .1);
                color: #409eff;
                font-weight: bold;
            }
        }
    }

    .el-container {
        padding: 25px 25px 0 25px;

        .el-form {
            width: 100%;
        }

        .el-tree {
            width: 100%;

            .collection-node {
                flex: 1;
                display: flex;
                align-items: center;
                justify-content: space-between;
                font-size: 14px;
                padding-right: 8px;

                span {
                    max-width: 380px;
                    overflow: hidden;
                    white-space: nowrap;
                    text-overflow: ellipsis;
                }
            }
        }

        .el-link {
            display: block;
        }
    }
}
</style>